/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.oszero.deliver.server.util;

import com.oszero.deliver.server.exception.SystemException;
import org.apache.commons.lang3.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;

/**
 * @BelongsProject: equipment-and-energy
 * @BelongsPackage: com.zjhn.common.utils
 * @Author: sxt
 * @CreateTime: 2023-06-17  10:05
 * @Description: 日期工具类
 * @Version: 1.0
 */
public class DateUtil {

    /**
     * 默认日期格式 yyyy-MM-dd HH:mm:ss
     */
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

    /**
     * 日期格式 yyyy-MM-dd
     */
    public static final String DATE_FORMAT = "yyyy-MM-dd";

    /**
     * 日期格式 yyyy-MM-dd
     */
    public static final String DATE_FORMAT_1 = "yy/MM/dd";
    public static final String DATE_FORMAT_2 = "MM/dd HH:mm";
    public static final String DATE_FORMAT_3 = "HH:mm";

    /**
     * 日期格式化对象
     */
    private static SimpleDateFormat sdf = new SimpleDateFormat();

    /**
     * 将日期对象按照指定的格式转换成字符串
     *
     * @param date
     * @param format
     * @return
     */
    public static String formatDateToString(Date date, String format) {
        synchronized (sdf) {
            sdf = new SimpleDateFormat(format);
            return sdf.format(date);
        }
    }

    /**
     * 将字符串对象按照指定的格式转换成日期
     *
     * @param date
     * @param format
     * @return
     */
    public static Date formatStringToDate(String date, String format) {
        try {
            if (StringUtils.isBlank(date))
                return null;
            synchronized (sdf) {
                sdf = new SimpleDateFormat(format);
                return sdf.parse(date);
            }
        } catch (ParseException e) {
            throw new SystemException("时间转换异常");
        }
    }

    /**
     * 将日期对象按照默认的格式转换成字符串
     *
     * @param date
     * @return
     */
    public static String formatDateToString(Date date) {
        if (date == null)
            return null;
        return formatDateToString(date, DEFAULT_DATE_FORMAT);
    }

    /**
     * 将字符串对象按照默认的格式转换成日期类型
     *
     * @param date
     * @return
     */
    public static Date formatStringToDate(String date) {
        try {
            if (date != null) {
                synchronized (sdf) {
                    sdf = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
                    return sdf.parse(date);
                }
            } else {
                return null;
            }
        } catch (ParseException e) {
            throw new SystemException("时间转换异常");
        }
    }

    /**
     * 指定时间增加/减少分钟数
     *
     * @param beginDate
     * @param min
     * @return
     */
    public static Date dateAddMinute(Date beginDate, Integer min) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(beginDate);
        calendar.add(Calendar.MINUTE, min); //减10分钟
        return calendar.getTime();
    }

    /**
     * 指定时间增加/减少天数
     *
     * @param beginDate
     * @param day
     * @return
     */
    public static Date dateAddDay(Date beginDate, Integer day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(beginDate);
        calendar.add(Calendar.DATE, day);
        return calendar.getTime();
    }

    /**
     * 指定时间增加/减少月份
     *
     * @param beginDate
     * @return
     */
    public static Date dateAddMonth(Date beginDate, Integer month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(beginDate);
        calendar.add(Calendar.MONTH, month);
        return calendar.getTime();
    }


    /**
     * 计算相隔天数 向上取整
     * @param start
     * @param end
     * @return
     */
    public static Integer intervalDays(Date start, Date end) {
        Long starTime = start.getTime();
        Long endTime = end.getTime();
        long num = endTime - starTime;//时间戳相差的毫秒数
        return (int) Math.ceil(num * 1.0 / (24 * 60 * 60 * 1000));
    }

    /**
     * 计算两个时间点分钟数
     * @param start
     * @param end
     * @return
     */
    public static Long intervalMinutes(String start, String end) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime dateTime1 = LocalDateTime.parse(start, formatter);
        LocalDateTime dateTime2 = LocalDateTime.parse(end, formatter);

        Duration duration = Duration.between(dateTime1, dateTime2);
        return duration.toMinutes();
    }

    /**
     * 间隔时间
     * @param begin HH:mm
     * @param end HH:mm
     * @return
     */
    public static Integer betweenMinute(String begin, String end) {
        if (begin.length() != 5)
            begin = 0 + begin;
        if (end.length() != 5)
            end = 0 + end;

        LocalTime localTime1 = LocalTime.parse(begin, DateTimeFormatter.ofPattern(DATE_FORMAT_3));
        LocalTime localTime2 = LocalTime.parse(end, DateTimeFormatter.ofPattern(DATE_FORMAT_3));

        long minutes = Duration.between(localTime1, localTime2).toMinutes();
        if (minutes < 0)
            // 跨天处理
            minutes = minutes + 24 * 60;

        return (int) minutes;
    }

    /**
     * 根据班次开始时间判断班次开始时间是今天还是昨天
     * @param startTime
     * @return
     */
    public static String getCurrentDay(String startTime, String endTime, Date date) {
        Date startDate = formatStringToDate(startTime, DATE_FORMAT_3);
        Date endDate = formatStringToDate(endTime, DATE_FORMAT_3);
        if (startDate.compareTo(endDate) > 0) {
            Date toDate = formatStringToDate(formatDateToString(date, DATE_FORMAT_3), DATE_FORMAT_3);
            if (toDate.compareTo(startDate) < 0) {
                // 获取昨天日期
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(date);
                calendar.add(Calendar.DATE, -1);
                return formatDateToString(calendar.getTime(), DATE_FORMAT);
            }
        }

        return formatDateToString(date, DATE_FORMAT);
    }

    /**
     * 获取两个时间点的秒数
     * @param beginTime yyyy-MM-dd HH:mm:ss
     * @param endTime yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static Integer betweenSecond(String beginTime, String endTime) {
        LocalDateTime startDateTime = LocalDateTime.parse(beginTime, DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT));
        LocalDateTime endDateTime = LocalDateTime.parse(endTime, DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT));

        Duration duration = Duration.between(startDateTime, endDateTime);
        long seconds = duration.getSeconds();

        return (int)seconds;
    }

    public static void main(String[] args) {
        Integer integer = betweenSecond("2023-12-21 10:00:00", "2023-12-21 10:10:00");
        System.out.println("integer = " + integer);
    }
}
